/**
******************************************************************************
* @file    六叶树CANFD二次开发demo
* @author  lys
* @version V1.1.0
* @date    2023
* @brief   用例功能:
* 以六叶树USBCANFDMini为例,设备通道CAN0配置为FD模式，仲裁域波特率为1M,数据波特率
* 5M,CAN总线收到什么数据就回复什么数据。支持:USBCANFDMini/USBCANFD1/USBCANFD2。
* @note
*
* @endverbatim
*
******************************************************************************
* 版权:长沙六叶树教育科技有限公司
* 官网:www.liuyeshu.cn
* 更多资料教程下载见官网
******************************************************************************
修改日期    版本号   修改者   功能描述
2023.04.10 V1.1.0   LYS
----------------------------------------------------------------------------
******************************************************************************
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include "ControlCAN.h"


void exit_can(int flag)
{
	//关闭设备
    LCAN_CloseDevice(LCAN_USBCANFDMini,0);
    exit(0);
}

//进程退出处理，程序调用 exit 或 main函数return 或 最后一个线程正常退出
void exitHandle(void)
{
	printf("Demo Stop...\n");
	//关闭设备
	LCAN_CloseDevice(LCAN_USBCANFDMini,0);
}

int main(void)
{
	LCAN_INITFD_CONFIG canInitFDCfgInfo;
	UINT devType=LCAN_USBCANFDMini,devIndex = 0,canIndex = 0,motornum = 6;

    LCAN_CANFD_OBJ fdObj[32], motorInit[motornum];
	UINT ret, i, j, frameCnt;

	printf("Demo Start...\n");

	// 初始化配置结构体
	memset(&canInitFDCfgInfo, 0, sizeof(LCAN_INITFD_CONFIG));

    //注册回调函数，程序调用 exit 或 mian函数return 或 最后一个线程正常退出时，捕获退出事件，执行退出处理
    atexit(exitHandle);

	//打开设备
	ret = LCAN_OpenDevice(devType, devIndex);
	if(LCAN_STATUS_OK != ret)
	{
		printf("Device Open Fail...\n");
		exit_can(1);
	}

	//FD MODE
	canInitFDCfgInfo.fdEn = 1;
	//ISO设置  0:NONE ISO 1:ISO
	canInitFDCfgInfo.isoEn = 0;
	//仲裁域波特率 1M
	canInitFDCfgInfo.abit_timing = 0x01400106;
	//数据域波特率 5M
	canInitFDCfgInfo.dbit_timing = 0x00800001;
	//正常工作模式
    canInitFDCfgInfo.mode = 0;

	//用例只初始化ch0
    ret = LCAN_InitCANFD(devType, devIndex, canIndex, &canInitFDCfgInfo);
    if(LCAN_STATUS_OK != ret)
    {
 		printf("Device Init Fail...\n");
		exit_can(1);
    }

    printf("\r\nDEMO 参数:CAN1 ISO:NONE Baud:<1M,5M>\n");

	while(1)
	{
	    //FD
		//send
		printf ("---fd send:%d\n", frameCnt);
		for (i=0; i<motornum; i++) {
			//正常发送模式
			motorInit[i].sendType = 0;
			motorInit[i].id = 1;
			motorInit[i].dataLen = 3;
			LCAN_TransmitFD(devType, devIndex, canIndex, motorInit[i], 1);
		}

		
		UINT rec_num = LCAN_GetReceiveNum(devType, devIndex, canIndex, REC_TYPE_FD);
		if(0 < rec_num)
		{
			frameCnt = LCAN_ReceiveFD(devType, devIndex, canIndex, fdObj, 32, 50); //返回帧数，实际的帧内容存在fdObj里面
			if(0 < frameCnt)
			{
				//print
				printf("---fd recv:%d\n", frameCnt);
				for (i=0; i<frameCnt; i++) {
					printf("ID: %08x DataLen:%02x ExternFlag:%d RemoteFlag: %d data:", 
					fdObj[i].id&0x1FFFFFFF, fdObj[i].dataLen, 
					fdObj[i].externFlag, fdObj[i].remoteFlag);
					for (j=0; j< fdObj[i].dataLen; j++) {
						printf("%02x ", fdObj[i].data[j]);
					}
					printf("\n");
				}
				
			}
		}

	}
	return 0;
}
